import base64
import pickle
from random import randint
from django.conf import settings
from django.http import HttpResponse
from rest_framework_jwt.views import ObtainJSONWebToken
from carts.utils import merge_cart_cookie_to_redis
from celery_tasks.meiduofunc.tasks import send_template_sms
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import CreateAPIView,RetrieveAPIView,UpdateAPIView,ListAPIView
from goods.models import SKU
from .models import User
from .serializers import UserSerializer, UserCenterSerializer, UseremailSerializer, BrowseHistorySerializer,SkuHistorySerializer, UpdatePassWordSerializer, \
    UpdateUserSerializer
from meiduo_hmh.utils import contones
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from meiduo_hmh.utils.captcha.captcha import captcha
from django.db.models import Q
from meiduo_hmh.libs.yuntongxun.sms import CCP  #报错但是可以正常使用,在pycharm中需要把包定义为Mark Directory的形式

# Create your views here.

class Sms_Code_View(APIView):

    def get(self,request,mobile):

        conn = get_redis_connection('sms_code')
        if conn.get('sms_code_flag:%s'%mobile):
            return Response({'message':'短信发送过于频繁'},status=status.HTTP_400_BAD_REQUEST)

        sms_code = '%06d'%randint(0,999999)
        print (sms_code)
        # conn = get_redis_connection('sms_code')
        pl = conn.pipeline()
        pl.setex('sms_code:%s'%mobile,contones.conton_sms_code_time,sms_code)
        pl.setex('sms_code_flag:%s'%mobile,contones.conton_sms_code_flag_time,'1')
        pl.execute()
        # ccp = CCP()
        # ccp.send_template_sms(mobiel,[sms_code,'5'],1)
        send_template_sms.delay(mobile,sms_code)

        return Response({'message':'ok'})

class UsernameView(APIView):

    def get(self,request,user):

        count = User.objects.filter(username=user).count()

        return Response({'count':count})

class Check_mobilesView(APIView):

    def get(self,request,mobiles):

        count = User.objects.filter(mobile=mobiles).count()

        return Response({'count':count})

class UsersView(CreateAPIView):

    serializer_class = UserSerializer

class UserView(RetrieveAPIView):

    serializer_class = UserCenterSerializer

    queryset = User.objects.all()

    def get_object(self):

        return self.request.user

class EmailView(UpdateAPIView):

    serializer_class = UseremailSerializer

    # queryset = User.objects.all()  #查询集并没有用到.但进行迁移的时候会报错？ 是因为这上面你定义了一个User与模型类名字一致了！！！

    def get_object(self):

        return self.request.user

class Check_emailView(APIView):

    def get(self,request):

        data = request.query_params
        token = data.get('token')
        if not token:
            return Response('无效的token!')

        tjs = TJS(settings.SECRET_KEY,300)
        try:
            str_token = tjs.loads(token)
        except:
            return Response({'message':'错误的token'},status=400)

        username = str_token.get('username')

        user = User.objects.filter(username=username)[0]

        if not user:
            return Response({'message':'验证的用户不存在'},status=400)

        user.email_active = True

        user.save()

        return Response({'email_active':user.email_active})

class BrowseHistoryView(CreateAPIView,ListAPIView):

    # serializer_class = BrowseHistorySerializer

    def get_queryset(self):

        user = self.request.user
        conn = get_redis_connection('history')
        redis_sku = conn.lrange('history_%s'%user.id,0,100)
        sku = SKU.objects.filter(id__in=redis_sku)
        # sku = SKU.objects.filter(id=1)
        return sku

    def get_serializer_class(self):

        if self.request.method == 'GET':
            return SkuHistorySerializer
        else:
            return BrowseHistorySerializer

class UserLoginView(ObtainJSONWebToken):

    def post(self, request, *args, **kwargs):

        response = super().post(request, *args, **kwargs)

        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            user = serializer.object.get('user') or request.user

            response = merge_cart_cookie_to_redis(request,response,user)

        return response

class UpdatePassWordViewBak(APIView): ##没有使用

    def put(self,request,pk):

        data = request.data
        try:
            user = User.objects.get(id=pk)
        except:
            return Response({'message':'用户名不存在!'})
        else:
            ser = UpdatePassWordSerializer(instance=user,data=data)
            ser.is_valid(raise_exception=True)
            ser.save()

        return Response(ser.data)

class UpdatePassWordView(UpdateAPIView):

    serializer_class = UpdatePassWordSerializer

    def get_queryset(self):

        user_id = self.kwargs['pk']

        return User.objects.filter(id=user_id)

class ImageCodeView(APIView):

    def get(self,request,image_code_id):

        image_uuid,image_code,image_data = captcha.generate_captcha()
        # ser = ImageSerializer(data=image_data)
        # ser.is_valid()
        # print(ser.errors)
        conn = get_redis_connection('image_code')
        conn.set('image_code:%s'%image_code_id,image_code,300)
        # response.content_type = 'image/png'
        # response.headers['Content-Type'] = 'image/png'
        # return Response(data,content_type='image/png') 'text/html'
        return HttpResponse(image_data,content_type='image/png')

class Check_UserView(APIView):

    def get(self,request,username):

        data = request.query_params
        try:
            user = User.objects.filter(Q(username=username)|Q(mobile=username))[0]
        except:
            user = None
        if not user:
            return Response('用户名或手机号不存在',status=404)
        image_code = data['text']
        image_codes_id = data['image_code_id']
        conn = get_redis_connection('image_code')
        redis_image_code = conn.get('image_code:%s'%image_codes_id)
        if not redis_image_code:
            return Response('验证码已失效!',status=400)
        if redis_image_code.decode().lower() != image_code.lower():
            return Response('验证码不正确',status=400)
        user_dict = {}
        user_dict['username'] = user.username
        user_dict['mobile'] = user.mobile
        token = base64.b64encode(pickle.dumps(user_dict))
        mobile = user.mobile
        new_mobile = mobile[0:3] + '****' + mobile[-4:]

        return Response({'mobile':new_mobile,'access_token':token})

class Sms_UserCodeView(APIView):

    def get(self,request):

        data = request.query_params
        access_token = data.get('access_token')
        user_dict = pickle.loads(base64.b64decode(access_token))
        user_mobile = user_dict.get('mobile')
        user_name = user_dict.get('username')

        try:
            user = User.objects.get(username=user_name)
        except:
            return Response({'message':'用户名不存在!'})

        conn = get_redis_connection('sms_code')
        if conn.get('sms_code_flag:%s' % user.id):
            return Response({'message': '短信发送过于频繁'}, status=status.HTTP_400_BAD_REQUEST)

        sms_code = '%06d' % randint(0, 999999)
        print(sms_code)
        pl = conn.pipeline()
        pl.setex('sms_code:%s' % user.id, contones.conton_sms_code_time, sms_code)
        pl.setex('sms_code_flag:%s' % user.id, contones.conton_sms_code_flag_time, '2')
        pl.execute()

        send_template_sms.delay(user_mobile, sms_code)

        return Response('ok')

class Sms_UserPasswordView(APIView):

    def get(self,request,username):

        data = request.query_params
        sms_code = data.get('sms_code')
        try:
            user = User.objects.filter(Q(username=username)|Q(mobile=username))[0]
        except:
            user = None
        if user is None:
            return Response('用户名不存在',status=404)

        conn = get_redis_connection('sms_code')
        redis_sms_code = conn.get('sms_code:%s'%user.id)
        if not redis_sms_code:
            return Response('手机号不存在',status=404)
        if redis_sms_code.decode() != sms_code:
            return Response('验证码错误',status=400)

        user_dict = {}
        user_dict['mobile'] = user.mobile
        user_dict['username'] = user.username
        access_token = base64.b64encode(pickle.dumps(user_dict))
        return Response({'user_id':user.id,'access_token':access_token})

class UpdateUserPasswordView(APIView):

    def post(self,request,pk):

        data = request.data
        try:
            user = User.objects.get(id=pk)
        except:
            user = None
        if user is None:
            return Response({'message':'用户不存在!'})
        ser = UpdateUserSerializer(instance=user,data=data)
        ser.is_valid()
        # print(ser.errors)
        ser.save()

        return Response('ok')


